package wator.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import wator.model.Agent;
import wator.model.Population;
import wator.model.Simulation;

public class SimulationRecorder implements Observer {
	
	int simulation_count=0;
	String filename;
	int pop_last_round;
	Simulation simulation;
	Population population;
	GnuplotWritter<Integer> gnuwritter;
	GnuplotWritter<Integer> confwritter;
	
	Vector<String> agentTypes;
	
	public SimulationRecorder(Simulation sim,String filename)
	{
		
		this.filename=filename;
		simulation=sim;
		simulation.addObserver(this);
		population=simulation.getPopulation();
		pop_last_round=0;
		
		agentTypes=new Vector<String>();
		
		
	}
	public void delete() throws IOException
	{
		if(gnuwritter!=null) gnuwritter.close();
	}
	
	private boolean newSimulation()
	{
		population=simulation.getPopulation();
		int round = population.getRound();
		boolean res = round==1 && round!=pop_last_round;
		//System.out.println("Round="+round);
		pop_last_round=round;
		return res;
	}
	 
	private void onNewSimulation() throws IOException
	{
		System.out.println("onNewSimulation");
		String name;
		if(filename.equals(""))
		{
			
			filename="results/"+GnuplotWritter.generateSimulationName();
			name=new String(filename);
			System.out.println(name);
		}
		else
		{
			name=new String("results/"+filename+"-"+simulation_count);
			System.out.println(name);
		}		
		
		if(gnuwritter==null)
			gnuwritter=new GnuplotWritter<Integer>(name);
		else 
		{
			gnuwritter.close();
			gnuwritter.open(name);
		}
		
		simulation_count++;
		
		//FInd agent types
		for(Agent agent : population)
		{	
			String[] temp=agent.toString().split("@");
			String[] temp2=temp[0].split("wator.model.agents.");
			String type=temp2[1];

			if(!agentTypes.contains(type))
				agentTypes.add(type);
		}
		gnuwritter.write("round\t");
		
		for(String t : agentTypes)
		{
			gnuwritter.write(t+"\t");
		}
		gnuwritter.write("\n");
		
		HashMap<String,Integer> agentNumbers=new HashMap<String,Integer>();
		//update
		for(Agent agent : population)
		{	
			String[] temp=agent.toString().split("@");
			String[] temp2=temp[0].split("wator.model.agents.");
			String type=temp2[1];

			if(agentNumbers.containsKey(type))
			{
				int number=agentNumbers.get(type);
				agentNumbers.put(type, number+1);
			}
			else 
				agentNumbers.put(type,1);
		}
		//we set to zero the agent that don't exist anymore
		for(String t : agentTypes)
		{
			if(!agentNumbers.containsKey(t))
				agentNumbers.put(t, 0);
		}
		//write in file
		Vector<Integer> pop=new Vector<Integer>();
		pop.add(population.getRound());
		for(String t : agentTypes)
		{
			pop.add(agentNumbers.get(t));
		}
		gnuwritter.write(pop);
	}
	
	public void update(Observable o, Object arg)
	{
		//System.out.println("UPDATE");
		if(o==simulation)
		{
			if(newSimulation()) 
			{
				try {
					onNewSimulation();
				} catch (Exception e) {
					e.printStackTrace();
				} 
			}
			else if(gnuwritter!=null)
			{
				HashMap<String,Integer> agentNumbers=new HashMap<String,Integer>();
				//update
				synchronized(population) {
				for(Agent agent : population)
				{	
					/*
					String[] temp=agent.toString().split("@");
					String[] temp2=temp[0].split("wator.model.agents.");
					String type=temp2[1];
					 */
					String type=Tools.extractAgentType(agent.toString());
					
					if(agentNumbers.containsKey(type))
					{
						int number=agentNumbers.get(type);
						agentNumbers.put(type, number+1);
					}
					else 
						agentNumbers.put(type,1);
				}
				}
				//we set to zero the agent that don't exist anymore
				for(String t : agentTypes)
				{
					if(!agentNumbers.containsKey(t))
						agentNumbers.put(t, 0);
				}
				//write in file
				Vector<Integer> pop=new Vector<Integer>();
				pop.add(population.getRound());
				for(String t : agentTypes)
				{
					pop.add(agentNumbers.get(t));
				}
				gnuwritter.write(pop);
			}
		}
	}
	
}
